package org.sheresam.springhbnjpa.test2.web.vaadin;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import com.vaadin.data.Property;
import com.vaadin.server.StreamVariable;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Slider;
import com.vaadin.ui.VerticalLayout;
import com.wcs.wcslib.vaadin.widget.multifileupload.ui.MultiFileUpload;
import com.wcs.wcslib.vaadin.widget.multifileupload.ui.UploadFinishedHandler;
import com.wcs.wcslib.vaadin.widget.multifileupload.ui.UploadStatePanel;
import com.wcs.wcslib.vaadin.widget.multifileupload.ui.UploadStateWindow;

@SuppressWarnings("serial")
public class MultiFileUploadWidgetTest extends VerticalLayout {

    private FormLayout form = new FormLayout();
    private UploadStateWindow uploadStateWindow = new UploadStateWindow();
    private UploadFinishedHandler uploadFinishedHandler;
    private double uploadSpeed = 50;

    
    public MultiFileUploadWidgetTest() {
        super();
        init();
    }


    protected void init() {
        setMargin(true);

        addLabels();

        addComponent(form);

        createForm();
    }

    private void createForm() {
        createUploadFinishedHandler();

        addSlowUploadExample("Single upload", false);
        addSlowUploadExample("Multiple upload", true);

        addWindowPositionSwitcher();
        addUploadSpeedSlider();
        addOverallProgressSwitcher();
    }

    private void addLabels() {
        addComponent(new Label("These upload fields use the same window for displaying an upload queue and a "
                + "progress indicator for each field."));
        addComponent(new Label("You can select multiple files to upload if your browser support it (Firefox, Chrome)."));
        addComponent(new Label("You can cancel the current upload or remove files from the upload queue."));
        addComponent(new Label("You can force the MultiFileUpload to behave like the stock Upload component."));
        addComponent(new Label("In browsers which not support HTML5, this field behaves like the stock Upload component with the shared window functionality."));
        addComponent(new Label("You can slow down and speed up the upload speed. This is for the demo only."));
    }

    private void createUploadFinishedHandler() {
        uploadFinishedHandler = new UploadFinishedHandler() {
            @Override
            public void handleFile(InputStream instream, String fileName, String mimeType, long length) {
                Notification.show(fileName + " uploaded.");
                
                try {
                    OutputStream outstream = new FileOutputStream("C:\\pramod\\temp\\tmp" + File.separator + fileName);
                    byte[] buffer = new byte[1024];
                    int len = instream.read(buffer);
                    while (len != -1) {
                        outstream.write(buffer, 0, len);
                        len = instream.read(buffer);
                    }
                    
                    outstream.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
    }

    private void addSlowUploadExample(String caption, boolean multiple) {
        SlowUpload slowUpload = new SlowUpload(uploadFinishedHandler, uploadStateWindow, multiple);
        int maxFileSize = 5242880; //5 MB
        slowUpload.setMaxFileSize(maxFileSize);
        String errorMsgPattern = "File is too big (max = {0}): {2} ({1})";
        slowUpload.setSizeErrorMsgPattern(errorMsgPattern);
        slowUpload.setCaption(caption);
        slowUpload.setPanelCaption(caption);
        slowUpload.getSmartUpload().setUploadButtonCaptions("Upload File", "Upload Files");
        form.addComponent(slowUpload);
    }

    private void addUploadSpeedSlider() {
        final Slider slider = new Slider("Delay (ms)");
        slider.setWidth("200px");
        slider.setImmediate(true);
        slider.setMin(0);
        slider.setMax(100);
        slider.setValue(uploadSpeed);
        slider.addValueChangeListener(new Property.ValueChangeListener() {
            @Override
            public void valueChange(Property.ValueChangeEvent event) {
                uploadSpeed = slider.getValue();
            }
        });
        form.addComponent(slider);
    }

    private void addWindowPositionSwitcher() {
        final ComboBox cb = new ComboBox("Window position");
        cb.setNullSelectionAllowed(false);
        for (UploadStateWindow.WindowPosition windowPosition : UploadStateWindow.WindowPosition.values()) {
            cb.addItem(windowPosition);
            cb.setItemCaption(windowPosition, windowPosition.name());
        }
        cb.setValue(UploadStateWindow.WindowPosition.CENTER);
        uploadStateWindow.setWindowPosition(UploadStateWindow.WindowPosition.CENTER);
        cb.addValueChangeListener(new Property.ValueChangeListener() {
            @Override
            public void valueChange(Property.ValueChangeEvent event) {
                uploadStateWindow.setWindowPosition((UploadStateWindow.WindowPosition) cb.getValue());
            }
        });
        form.addComponent(cb);
    }

    private void addOverallProgressSwitcher() {
        final CheckBox cb = new CheckBox("Overall progress");
        cb.setValue(true);
        cb.addValueChangeListener(new Property.ValueChangeListener() {
            @Override
            public void valueChange(Property.ValueChangeEvent event) {
                uploadStateWindow.setOverallProgressVisible(cb.getValue());
            }
        });
        form.addComponent(cb);
    }

    private class SlowUpload extends MultiFileUpload {

        public SlowUpload(UploadFinishedHandler handler, UploadStateWindow uploadStateWindow) {
            super(handler, uploadStateWindow, true);
        }

        public SlowUpload(UploadFinishedHandler handler, UploadStateWindow uploadStateWindow, boolean multiple) {
            super(handler, uploadStateWindow, multiple);
        }

        @Override
        protected UploadStatePanel createStatePanel(UploadStateWindow uploadStateWindow) {
            return new SlowUploadStatePanel(uploadStateWindow);
        }

    }

    private class SlowUploadStatePanel extends UploadStatePanel {

        public SlowUploadStatePanel(UploadStateWindow window) {
            super(window);
        }

        @Override
        public void onProgress(StreamVariable.StreamingProgressEvent event) {
            try {
                Thread.sleep((int) uploadSpeed);
            } catch (InterruptedException ex) {
                
            }
            super.onProgress(event);
        }
    }
}